package vectors;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StreamTokenizer;
import java.io.Writer;
import java.util.Random;

import main.Sort;

public class Vectors {
	static private VectorFactory factory;

	static {
		factory = new ArrayVectorFactory();
	}

	public static Vector multiplyVectorByNumber(Vector v, double number) {
		Vector result = factory.createVector(v.getLength());
		result.fillFromAnotherVector(v);
		result.multiplyByNumber(number);
		return result;
	}

	public static Vector addVectors(Vector v1, Vector v2) {
		Vector result = factory.createVector(v1.getLength());
		result.fillFromAnotherVector(v1);
		result.add(v2);
		return result;
	}

	public static void sortVector(Vector v) {
		Sort.sortVector(v);
	}

	public static Vector generate(int length) {
		Vector result = factory.createVector(length);
		Random rand = new Random();
		double[] values = new double[length];
		for (int i = 0; i < length; i++) {
			values[i] = 100 * rand.nextDouble();
		}
		result.fillFromAnArray(values);
		return result;
	}

	public static void outputVector(Vector v, OutputStream out) {
		DataOutputStream s = new DataOutputStream(out);
		int length = v.getLength();
		try {
			s.writeInt(length);
			for (int i = 0; i < length; i++) {
				s.writeDouble(v.getElement(i));
			}
			s.flush();
		} catch (IOException e) {
			System.out.println("Some error occurred!");
		}
	}

	public static Vector inputVector(InputStream in) {
		Vector v = null;
		DataInputStream s = new DataInputStream(in);
		try {
			int length = s.readInt();
			double[] vals = new double[length];
			for (int i = 0; i < length; i++) {
				vals[i] = s.readDouble();
			}
			v = factory.createVector();
			v.fillFromAnArray(vals);
		} catch (IOException e) {
			System.out.println("Some error occurred!");
		}
		return v;
	}

	public static void writeVector(Vector v, Writer out) {
		PrintWriter w = new PrintWriter(out);
		int length = v.getLength();
		w.print(length + " ");
		for (int i = 0; i < length; i++) {
			w.print(v.getElement(i) + " ");
		}
		w.println();
		w.flush();
	}

	public static Vector readVector(Reader in) {
		Vector v = null;
		StreamTokenizer t = new StreamTokenizer(in);
		try {
			t.nextToken();
			int length = (int) t.nval;
			double[] vals = new double[length];
			for (int i = 0; i < length; i++) {
				t.nextToken();
				vals[i] = t.nval;
			}
			v = factory.createVector();
			v.fillFromAnArray(vals);
		} catch (IOException e) {
			System.out.println("Some error occurred!");
		}
		return v;
	}

	public static void setVectorFactory(VectorFactory f) {
		factory = f;
	}

	public static Vector createInstance(int size) {
		return factory.createVector(size);
	}

	public static Vector createInstance() {
		return factory.createVector();
	}
}
